/*
 * Copyright 2013 Sigurd Randoll.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.digiway.rapidbreeze.client.controller;

import de.digiway.rapidbreeze.client.controller.downloadtable.DownloadTableController;
import de.digiway.rapidbreeze.client.config.ClientConfiguration;
import de.digiway.rapidbreeze.client.config.ServerConfiguration;
import de.digiway.rapidbreeze.client.infrastructure.BusEvents;
import de.digiway.rapidbreeze.client.infrastructure.ConnectionWatchdog;
import de.digiway.rapidbreeze.client.infrastructure.I18n;
import de.digiway.rapidbreeze.client.infrastructure.cnl.ClickAndLoadServer;
import de.digiway.rapidbreeze.client.model.collector.UrlInformationResourceService;
import de.digiway.rapidbreeze.client.model.collector.UrlInformationResourceServiceFactory;
import de.digiway.rapidbreeze.client.model.download.DownloadResourceRepository;
import de.digiway.rapidbreeze.client.model.download.DownloadResourceRepositoryFactory;
import de.digiway.rapidbreeze.client.model.info.ServerInformationResourceService;
import de.digiway.rapidbreeze.client.model.info.ServerInformationResourceServiceFactory;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Logger;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.rribbit.Listener;
import org.rribbit.creation.ObjectBasedListenerObjectCreator;
import org.rribbit.util.RRiBbitUtil;

/**
 * JavaFX main client view controller.
 *
 * @author Sigurd
 */
public class ClientController implements Initializable {
    
    @FXML
    private DownloadTableController downloadTableController;
    @FXML
    private ToolbarController toolbarController;
    @FXML
    private SpeedControlController speedControlController;
    @FXML
    private StatusbarController statusbarController;
    private LinkCollectorController linkCollectorController;
    private DownloadResourceRepository downloadResourceRepository;
    private ClientConfiguration clientConfiguration;
    private ServerConfiguration serverConfiguration;
    private ServerInformationResourceService serverInformationResourceService;
    private UrlInformationResourceService urlInformationResourceService;
    private Stage downloadCollectorStage;
    private ClickAndLoadServer clickAndLoadServer;
    public static final String LINK_COLLECTOR_WINDOW_FXML = "/fxml/LinkCollectorWindow.fxml";
    private static final Logger LOG = Logger.getLogger(ClientController.class.getName());

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        this.downloadResourceRepository = DownloadResourceRepositoryFactory.getInstance();
        this.clientConfiguration = ClientConfiguration.getInstance();
        this.serverConfiguration = ServerConfiguration.getInstance();
        this.serverInformationResourceService = ServerInformationResourceServiceFactory.getInstance();
        this.urlInformationResourceService = UrlInformationResourceServiceFactory.getInstance();
        
        this.downloadTableController.setDownloadResourceRepository(downloadResourceRepository);
        this.downloadTableController.setClientConfiguration(clientConfiguration);
        
        this.statusbarController.setClientConfiguration(clientConfiguration);
        
        this.speedControlController.setServerConfiguration(serverConfiguration);
        
        initLinkCollectorWindow();
        registerEventBus();
        startConnectionWatchdog();
        startServerConfigurationChangeListener();
        startClickAndLoadServer();
    }
    
    private void registerEventBus() {
        ObjectBasedListenerObjectCreator creator = new ObjectBasedListenerObjectCreator(this, statusbarController, downloadTableController, linkCollectorController, speedControlController);
        RRiBbitUtil.createRequestResponseBusForLocalUse(creator, true);
    }
    
    private void startConnectionWatchdog() {
        ConnectionWatchdog watchdog = new ConnectionWatchdog(clientConfiguration, serverInformationResourceService);
        watchdog.start();
    }
    
    public void setParentStage(Stage stage) {
        downloadCollectorStage.initOwner(stage);
    }
    
    @Listener(hint = BusEvents.OPEN_DOWNLOAD_COLLECTOR_WINDOW)
    public void onOpenDownloadCollectorWindow() {
        if (!downloadCollectorStage.isShowing()) {
            downloadCollectorStage.show();
        }
    }
    
    @Listener(hint = BusEvents.CLOSE_DOWNLOAD_COLLECTOR_WINDOW)
    public void onCloseDownloadCollectorWindow() {
        if (downloadCollectorStage.isShowing()) {
            downloadCollectorStage.hide();
        }
    }
    
    private void initLinkCollectorWindow() {
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource(LINK_COLLECTOR_WINDOW_FXML));
            loader.setResources(I18n.getInstance().getResourceBundle());
            loader.load();
            
            Parent root = loader.getRoot();
            linkCollectorController = loader.getController();
            linkCollectorController.setInformationResourceService(urlInformationResourceService);
            linkCollectorController.setDownloadResourceRepository(downloadResourceRepository);
            downloadCollectorStage = new Stage(StageStyle.UTILITY);
            downloadCollectorStage.initModality(Modality.WINDOW_MODAL);
            downloadCollectorStage.setScene(new Scene(root));
            downloadCollectorStage.setTitle(I18n.getInstance().getResourceBundle().getString("DownloadCollector.Title"));
        } catch (IOException ex) {
            throw new IllegalStateException("Cannot initialize modal dialog.", ex);
        }
    }
    
    private void startClickAndLoadServer() {
        clickAndLoadServer = new ClickAndLoadServer();
        if (clickAndLoadServer.isPortAvailable()) {
            clickAndLoadServer.start();
        } else {
            LOG.warning("Cannot start CNL-Server because port is in use.");
        }
    }
    
    private void startServerConfigurationChangeListener() {
        serverConfiguration.startMonitoring();
    }
}
